<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Controller\Api;

use App\Middleware\JwtMiddleware;
use App\Model\Upload;
use App\Model\User;
use App\Server\Wechat;
use Hyperf\Di\Annotation\Inject;
use Hyperf\HttpServer\Annotation\Controller;
use Hyperf\HttpServer\Annotation\Middleware;
use Hyperf\HttpServer\Annotation\RequestMapping;
use Hyperf\HttpServer\Contract\RequestInterface;
use Hyperf\Validation\Contract\ValidatorFactoryInterface;
use Hyperf\Validation\Rule;

#[Controller]
class UserController
{
    #[Inject]
    protected ValidatorFactoryInterface $validationFactory;

    #[Inject]
    protected RequestInterface $request;

    #[RequestMapping(path: "getOpenid", methods: "post")]
    /**
     * 获取用户openid
     * @return false|string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getOpenid()
    {
        $data = $this->validationFactory->make(
            $this->request->all(),
            [
                'code' => 'required',
            ],
            [
                'code.required' => '获取jsCode失败'
            ]
        );

        if ($data->fails()) {
            // Handle exception
            $errorMessage = $data->errors()->first();
            return self::jsonResponse(422, $errorMessage, ['openid' => '']);
        }

        $data = $data->validated();

        $wechat = new Wechat();
        $openid = $wechat->code2Session($data['code']);
        return self::jsonResponse(200, 'success', ['openid' => $openid]);
    }

    #[RequestMapping(path: "getPhoneNumber", methods: "post")]
    /**
     * 获取手机号
     * @return false|string
     * @throws \GuzzleHttp\Exception\GuzzleException
     */
    public function getPhoneNumber()
    {
        $data = $this->validationFactory->make(
            $this->request->all(),
            [
                'code' => 'required',
            ],
            [
                'code.required' => '获取jsCode失败'
            ]
        );

        if ($data->fails()) {
            // Handle exception
            $errorMessage = $data->errors()->first();
            return self::jsonResponse(422, $errorMessage, ['mobile' => '']);
        }

        $data = $data->validated();
        $wechat = new Wechat();
        $mobile = $wechat->getPhoneNumber($data['code']);
        return self::jsonResponse(200, 'success', ['mobile' => $mobile]);
    }

    #[RequestMapping(path: "login", methods: "post")]
    /**
     * 登录
     * @return false|string
     */
    public function login()
    {
        $data = $this->validationFactory->make(
            $this->request->all(),
            [
                'openid' => '',
                'mobile' => '',
                'header' => '',
                'nickname' => ''
            ],
        );

        $data = $data->validated();

        if (!($data['openid'] ?? '') && !($data['mobile'])) {
            return self::jsonResponse(422, '参数缺失');
        }

        //查找用户
        if (($data['openid'] ?? '')) {
            $user = User::getByOpenid($data['openid']);
        } else {
            $user = User::getByMobile($data['mobile']);
        }

        //没有用户信息则创建用户
        if (!$user) {
            $user = new User();
            $user->nickname = $data['nickname'] ?? '用户' . time();
            if (($data['header'] ?? '')) {
                $upload = new Upload();
                $upload->url = $data['header'];
                $upload->save();

                $user->header_img_id = $upload->id;
            }
            $user->openid = $data['openid'] ?? '';
            $user->mobile = $data['mobile'] ?? '';

            $user->save();
        }

        //JWT登录创建token
        $token = auth()->login($user);

        $data = [
            'token' => $token,
            'token_type' => 'bearer',
            'user' => $user->toApi(),
        ];

        return self::jsonResponse(200, 'success', $data);
    }

    #[Middleware(JwtMiddleware::class)]
    #[RequestMapping(path: "detail", methods: "get")]
    /**
     * 用户详情
     * @return false|string
     */
    public function detail()
    {
        $user = auth()->user();
        return self::jsonResponse(200, 'success', $user->toApi());
    }

    #[Middleware(JwtMiddleware::class)]
    #[RequestMapping(path: "edit", methods: "post")]
    /**
     * 编辑资料
     * @return false|string
     */
    public function edit()
    {
        /** @var User $user */
        $user = auth()->user();
        $data = $this->validationFactory->make(
            $this->request->all(),
            [
                'header_img_id' => 'required',
                'nickname' => 'required',
                'mobile' => [
                    'required',
                    Rule::unique('user')->where(function ($q) use ($user) {
                        $q->whereNull('delete_time')->where('id', '!=', $user->id);
                    })
                ],
            ],
            [
                'header_img_id.required' => '请上传头像',
                'nickname.required' => '请填写昵称',
                'mobile.required' => '请填写手机号',
                'mobile.unique' => '手机号已被占用',
            ]
        );

        if ($data->fails()) {
            return self::jsonResponse(422, $data->errors()->first());
        }

        $data = $data->validated();
        $user->fill($data);
        $user->save();

        return self::jsonResponse(200, 'success');
    }

    public static function jsonResponse(int $status = 1, $message = 'success', $data = null, $headerStatus = 200)
    {
        if (is_array($message)) {
            $data = $message;
            $message = 'success';
        }
        if (empty($data)) {
            $data = new class {
            };
        }

        return json_encode(['status' => $status, 'message' => $message, 'data' => $data]);

//        return response()->json(
//            ['status' => $status, 'message' => $message, 'data' => $data],
//            $headerStatus,
//            [],
//            JSON_UNESCAPED_UNICODE
//        );
    }
}
